package com.xiaozhu.controller;

import com.xiaozhu.anno.RolePermission;
import com.xiaozhu.pojo.DTO.UserDto;
import com.xiaozhu.pojo.Entity.User;
import com.xiaozhu.pojo.JwtProperties;
import com.xiaozhu.pojo.Result;
import com.xiaozhu.pojo.VO.UserVo;
import com.xiaozhu.service.LoginService;
import com.xiaozhu.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 朱慧军
 * @version 1.1 优化缓存和权限策略
 */
@RestController
@RequestMapping()
@Slf4j
public class LoginController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private RedisTemplate redisTemplate;




    /**
     * 用户登录
     */
    @PostMapping("/auth/login")
    public Result login(@RequestBody UserDto userDto) {
        log.info("前端传递的数 {}", userDto);
        User user = loginService.login(userDto);

        // 普通用户无权限时，给个默认值避免 NPE
        if (user.getCode() == null) {
            user.setCode("user");
        }

        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("role", user.getRole());
        claims.put("perms", user.getCode());

        String token = JwtUtils.createToken(jwtProperties.getSecretKey(), jwtProperties.getTtl(), claims);

        UserVo userVo = UserVo.builder()
                .id(user.getId())
                .username(user.getUsername())
                .password(user.getPassword())
                .token(token)
                .build();

        return Result.success(userVo);
    }

    /**
     * 注册
     */
    @PostMapping("/user/add")
    public Result add(@RequestBody UserDto userDto) {
        log.info("前端传递的数 {}", userDto);
        loginService.add(userDto);
        return Result.success();
    }

    /**
     * 管理员查询所有用户
     * 第一次查数据库，之后直接从缓存读取
     */
    @Cacheable(cacheNames = "userCache", key = "'allUsers'")
    @RolePermission(value = {"admin"}, url = {"/user/list"})
    @GetMapping("/user/list")
    public Result list() {
        log.info("查询所有用户");
        List<User> userList = loginService.userList();
        return Result.success(userList);
    }

    /**
     * 设置管理员
     * 更新后刷新缓存（重新执行 list 方法，并覆盖缓存）
     */
    @CachePut(cacheNames = "userCache", key = "'allUsers'")
    @RolePermission(value = {"admin"}, url = {"/admin/add"})
    @PostMapping("/admin/add")
    public Result addAdmin(@RequestParam("id") Long userId) {
        loginService.addAdmin(userId);
        // 返回最新用户列表，缓存会被更新
        return Result.success();
    }

    /**
     * 删除用户
     * 删除成功后清除缓存，下次查询会重新加载
     */
    @CacheEvict(cacheNames = "userCache", key = "'allUsers'")
    @RolePermission(value = {"admin"}, url = {"/admin/delete"})
//    @RolePermission(value = {"admin", "user"}, url = {"/admin/delete", "/user/delete"})
    @DeleteMapping("/admin/delete")
    public Result delete(@RequestParam List<Long> ids) {
        loginService.delete(ids);
        return Result.success();
    }

    @GetMapping("/user/info")
    public Result info(@RequestParam(value = "id") Long userId) {
        log.info("查询员工信息");

        // 构建redis中key, 规则：user:员工id
        String key = "user:" + userId;

        // 缓存： 从redis中查询是否存在当前用户
        UserVo userinfo =(UserVo) redisTemplate.opsForValue().get(key);
        if (userinfo != null) {
            log.info("缓存读取数据：{}",userinfo);
            return Result.success(userinfo);
        }

        UserVo user = loginService.info(userId);

        redisTemplate.opsForValue().set(key, user);

        return Result.success(user);


    }

}
